package com.baselibrary.utils;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import java.util.List;

public class FileUtils {

    public static String getPath() {
        return ContextUtils.getCurApplication().getExternalFilesDir(null) + File.separator;
    }

    public static void copyVideoFile(String sourcePath, OnCopyFileListener onCopyFileListener) {
        String appPath = StorageUtils.getAppPath(StorageUtils.TEMP_PATH);
        String newPath = appPath + "/" + System.currentTimeMillis() + ".mp4";
        if (onCopyFileListener == null)
            return;
        FileChannel in = null;
        FileChannel out = null;
        FileInputStream inStream = null;
        FileOutputStream outStream = null;
        File source = new File(sourcePath);
        File target = new File(newPath);
        try {
            FileUtils.makeDirs(target.getAbsolutePath());
            inStream = new FileInputStream(source);
            outStream = new FileOutputStream(target);
            in = inStream.getChannel();
            out = outStream.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(4096);
            while (in.read(buffer) != -1) {
                //onCopyFileListener.onCopyIng();
                buffer.flip();
                out.write(buffer);
                buffer.clear();
            }
            onCopyFileListener.onCopyOver(newPath);
        } catch (IOException e) {
            e.printStackTrace();
            onCopyFileListener.onCopyError();
        } finally {
            close(inStream);
            close(in);
            close(outStream);
            close(out);
        }
    }

    public static File createPosterFile() {
        // 首先保存图片 创建文件夹
        File appDir = new File(Environment.getExternalStorageDirectory(), "hanke_share");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        //图片文件名称
        String fileName = "hanke_share" + System.currentTimeMillis() + ".jpg";
        return new File(appDir, fileName);
    }

    public static String getMasterPath() {
        return getPath() + "master" + File.separator;
    }


    public static String getTempPath() {
        return getMasterPath() + "temp" + File.separator;
    }


    public static String getAppPath() {
        return Environment.getExternalStorageDirectory() + File.separator + "酣享" + File.separator;
    }

    public static File createTempFile(String fileName) {
        if (!CommonUtil.isBlank(fileName)) {
            try {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    File file = new File(getTempPath() + fileName);
                    file.getParentFile().mkdirs();
                    if (file.exists()) {
                        file.delete();
                    }
                    file.createNewFile();
                    return file;
                } else {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        } else {
            return null;
        }
    }


    public static String saveBitmap(Bitmap b) {
        String jpegName = System.currentTimeMillis() + "_cover.jpg";
        File jpegPath = createTempFile(jpegName);
        try {
            FileOutputStream fout = new FileOutputStream(jpegPath);
            BufferedOutputStream bos = new BufferedOutputStream(fout);
            b.compress(Bitmap.CompressFormat.JPEG, 70, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jpegPath.getPath();
    }


    public static void compressBmpToFile(Bitmap bmp, File file, int option) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int options = 100;//个人喜欢从80开始,
        bmp.compress(Bitmap.CompressFormat.PNG, options, baos);
        while (baos.toByteArray().length / 1024 > option) {
            baos.reset();
            options -= 5;
            if (options < 0) {
                options = 5;
                bmp.compress(Bitmap.CompressFormat.PNG, options, baos);
                break;
            }
            bmp.compress(Bitmap.CompressFormat.PNG, options, baos);
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            bmp.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //固定值
    public static void compressBmpToFile4Fixed(Bitmap bmp, File file, int option) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, option, baos);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            bmp.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static File getTempFileName(String picPath) {
        String fileName = picPath.substring(picPath.lastIndexOf("/") + 1);
        File file = FileUtils.createTempFile(fileName);
        return file;
    }

    //删除文件夹里面的文件
    public static boolean deleteAllFile(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return false;
        File[] files = dir.listFiles();
        if (files == null) return true;
        for (File file : files) {
            if (file.isFile()) {
                file.delete(); // 删除所有文件
            }
        }
        return true;
    }

    //判断文件是否存在
    public static boolean fileIsExists(String strFile) {
        try {
            File f = new File(strFile);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    // 生成文件夹
    public static File makeRootDirectory(String filePath) {
        File file = null;
        try {
            file = new File(filePath);
            if (!file.exists()) {
                file.mkdir();
            }
            return file;
        } catch (Exception e) {
            return new File("");
        }
    }

    public static void clearDownloadWidgetFile(String path) {
        if (clearIsFileExists(path)) {
            File file = new File(path);
            delete(file);
        } else {
        }
    }

    public static void clearFile() {
        if (clearIsFileExists(getPath())) {
            File file = new File(getPath());
            delete(file);
        } else {
        }
    }

    public static boolean clearIsFileExists(String path) {
        if (CommonUtil.isBlank(path)) {
            return false;
        }
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        try {
            if (file.exists()) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static void delete(File file) {
        if (file.isFile()) {
            file.delete();
            return;
        }

        if (file.isDirectory()) {
            File[] childFiles = file.listFiles();
            if (childFiles == null || childFiles.length == 0) {
                file.delete();
                return;
            }

            for (int i = 0; i < childFiles.length; i++) {
                delete(childFiles[i]);
            }
            file.delete();
        }
    }

    public static String getJson(String fileName, Context context) {
        //将json数据变成字符串
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //获取assets资源管理器
            AssetManager assetManager = context.getAssets();
            //通过管理器打开文件并读取
            BufferedReader bf = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    public static String[] getHistoryList(Context context) {
        // 获取搜索记录文件内容
        SharedPreferences sp = context.getSharedPreferences("search_history", 0);
        String history = sp.getString("history", "");
//        Log.e(TAG, "getHistoryList: " + history);
        // 用逗号分割内容返回数组
        String[] history_arr = history.split(",");
        // 保留前50条数据
        if (history_arr.length > 3) {
            String[] newArrays = new String[3];
            System.arraycopy(history_arr, history_arr.length - 3, newArrays, 0, 3);
            return newArrays;
        }
        return history_arr;
    }

    private static final String[][] MIME_MapTable = new String[][]{{".3gp", "video/3gpp"}, {".apk", "application/vnd.android.package-archive"}, {".asf", "video/x-ms-asf"}, {".avi", "video/x-msvideo"}, {".bin", "application/octet-stream"}, {".bmp", "image/bmp"}, {".c", "text/plain"}, {".class", "application/octet-stream"}, {".conf", "text/plain"}, {".cpp", "text/plain"}, {".doc", "application/msword"}, {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, {".xls", "application/vnd.ms-excel"}, {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, {".exe", "application/octet-stream"}, {".gif", "image/gif"}, {".gtar", "application/x-gtar"}, {".gz", "application/x-gzip"}, {".h", "text/plain"}, {".htm", "text/html"}, {".html", "text/html"}, {".jar", "application/java-archive"}, {".java", "text/plain"}, {".jpeg", "image/jpeg"}, {".jpg", "image/jpeg"}, {".js", "application/x-javascript"}, {".log", "text/plain"}, {".m3u", "audio/x-mpegurl"}, {".m4a", "audio/mp4a-latm"}, {".m4b", "audio/mp4a-latm"}, {".m4p", "audio/mp4a-latm"}, {".m4u", "video/vnd.mpegurl"}, {".m4v", "video/x-m4v"}, {".mov", "video/quicktime"}, {".mp2", "audio/x-mpeg"}, {".mp3", "audio/x-mpeg"}, {".mp4", "video/mp4"}, {".mpc", "application/vnd.mpohun.certificate"}, {".mpe", "video/mpeg"}, {".mpeg", "video/mpeg"}, {".mpg", "video/mpeg"}, {".mpg4", "video/mp4"}, {".mpga", "audio/mpeg"}, {".msg", "application/vnd.ms-outlook"}, {".ogg", "audio/ogg"}, {".pdf", "application/pdf"}, {".png", "image/png"}, {".pps", "application/vnd.ms-powerpoint"}, {".ppt", "application/vnd.ms-powerpoint"}, {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, {".prop", "text/plain"}, {".rc", "text/plain"}, {".rmvb", "audio/x-pn-realaudio"}, {".rtf", "application/rtf"}, {".sh", "text/plain"}, {".tar", "application/x-tar"}, {".tgz", "application/x-compressed"}, {".txt", "text/plain"}, {".wav", "audio/x-wav"}, {".wma", "audio/x-ms-wma"}, {".wmv", "audio/x-ms-wmv"}, {".wps", "application/vnd.ms-works"}, {".xml", "text/plain"}, {".z", "application/x-compress"}, {".zip", "application/x-zip-compressed"}, {"", "*/*"}};

    // 打开文件（外应用）
    public static void openFile(Context context, File file) {
        try {
            Intent intent = new Intent();
            ComponentName cop = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI");
            intent.setComponent(cop);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            intent.setAction("android.intent.action.VIEW");
            intent.setAction(Intent.ACTION_SEND);
            String type = getMIMEType(file);
            Uri fileUri;
            if (Build.VERSION.SDK_INT >= 24) {
                fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".FileProvider", file);
                intent.setDataAndType(fileUri, type);
                grantUriPermission(context, fileUri, intent);
            } else {
                fileUri = Uri.fromFile(file);
                intent.setDataAndType(fileUri, type);
            }
            intent.putExtra(Intent.EXTRA_STREAM, fileUri);
            context.startActivity(intent);
        } catch (Exception var6) {
            var6.printStackTrace();
        }

    }

    private static void grantUriPermission(Context context, Uri fileUri, Intent intent) {
        List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        Iterator var4 = resInfoList.iterator();

        while (var4.hasNext()) {
            ResolveInfo resolveInfo = (ResolveInfo) var4.next();
            String packageName = resolveInfo.activityInfo.packageName;
            context.grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }

    }

    private static String getMIMEType(File file) {
        String type = "*/*";
        String fName = file.getName();
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex < 0) {
            return type;
        } else {
            String end = fName.substring(dotIndex, fName.length()).toLowerCase();
            if (end == "") {
                return type;
            } else {
                for (int i = 0; i < MIME_MapTable.length; ++i) {
                    if (end.equals(MIME_MapTable[i][0])) {
                        type = MIME_MapTable[i][1];
                    }
                }

                return type;
            }
        }
    }


    public static String getCacheDirPath(Context context) {
        return context.getCacheDir().getAbsolutePath() + "/";
    }


    public static String getMediaSuffixName(File file) {
        if (file == null) return null;

        String filename = file.getName();

        if (filename.lastIndexOf(".") == -1)
            return "";//文件没有后缀名的情况
        return filename.substring(filename.lastIndexOf("."));

    }

    public static void copySdcardFile(File fromFile, File toFile) {
        try {
            InputStream fosfrom = new FileInputStream(fromFile);
            OutputStream fosto = new FileOutputStream(toFile);
            byte bt[] = new byte[1024];
            int c;
            while ((c = fosfrom.read(bt)) > 0) {
                fosto.write(bt, 0, c);
            }
            fosfrom.close();
            fosto.close();
        } catch (Exception ex) {
            ex.getMessage();
        }
    }


    /**
     * 关闭流
     *
     * @param closeables Closeable
     */
    @SuppressWarnings("WeakerAccess")
    public static void close(Closeable... closeables) {
        if (closeables == null || closeables.length == 0)
            return;
        for (Closeable closeable : closeables) {
            if (closeable != null) {
                try {
                    closeable.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public interface OnCopyFileListener {

        void onCopyOver(String filePath);

        void onCopyError();
    }

    public static boolean makeDirs(@NonNull String filePath) {
        String folderName = getFolderName(filePath);
        if (TextUtils.isEmpty(folderName)) {
            return false;
        }

        File folder = new File(folderName);
        return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs();
    }

    @NonNull
    public static String getFolderName(@NonNull String filePath) {

        if (TextUtils.isEmpty(filePath)) {
            return filePath;
        }

        int filePosi = filePath.lastIndexOf(File.separator);
        return (filePosi == -1) ? "" : filePath.substring(0, filePosi);
    }

    public static boolean deleteFile(@NonNull String path) {

        if (TextUtils.isEmpty(path)) {
            return true;
        }

        File file = new File(path);
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        if (!file.isDirectory()) {
            return false;
        }
        File[] filesList = file.listFiles();

        if (filesList != null) {
            for (File f : filesList) {
                if (f.isFile()) {
                    f.delete();
                } else if (f.isDirectory()) {
                    deleteFile(f.getAbsolutePath());
                }
            }
        }

        return file.delete();
    }

    public static boolean fileRename(@NonNull String fromName, @NonNull String toName) {
        // TODO: 根据文件名判断是否属于同一挂载点
        File fromFile = new File(fromName);
        File toFile = new File(toName);
        if (!fromFile.exists()) {
            return false;
        }
        boolean result = fromFile.renameTo(toFile);
        if (result) {
        }
        return result;
    }

    //打开指定文件夹
    public static void openAssignFolder(Context context, String path) {
        File file = new File(path);
        if (null == file || !file.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        FileProviderUtils.setIntentDataAndType(context, intent, "*/*", file, false);
        try {
            context.startActivity(intent);
//            startActivity(Intent.createChooser(intent,"选择浏览工具"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
